package com.foreverwin.jzymes.production.tool.service.impl;


import com.foreverwin.jzymes.common.constant.Constants;
import com.foreverwin.jzymes.common.service.*;
import com.foreverwin.jzymes.common.util.BOHandleUtil;
import com.foreverwin.jzymes.common.util.CommonMethods;
import com.foreverwin.jzymes.framework.exception.BusinessException;
import com.foreverwin.jzymes.framework.util.I18nUtil;
import com.foreverwin.jzymes.production.program.domain.CncProgram;
import com.foreverwin.jzymes.production.program.service.ICncProgramAdviceService;
import com.foreverwin.jzymes.production.program.service.ICncProgramService;
import com.foreverwin.jzymes.production.tool.domain.ToolBill;
import com.foreverwin.jzymes.production.tool.domain.ToolBillItem;
import com.foreverwin.jzymes.production.tool.mapper.ToolBillAdviceMapper;
import com.foreverwin.jzymes.production.tool.mapper.ToolBillItemMapper;
import com.foreverwin.jzymes.production.tool.service.IToolBillAdviceService;
import com.foreverwin.jzymes.production.tool.service.IToolBillItemService;
import com.foreverwin.jzymes.production.tool.service.IToolBillService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.*;

@Service
public class ToolBillAdviceServiceImpl implements IToolBillAdviceService {
    @Autowired
    IFieldGroupAdviceService fieldGroupAdviceService;
    @Autowired
    ISiteAdviceService siteAdviceService;
    @Autowired
    IItemGroupAdviceService itemGroupAdviceService;
    @Autowired
    IToolBillService toolBillService;
    @Autowired
    IToolBillItemService toolBillItemService;
    @Autowired
    IToolAdiviceService toolAdiviceService;
    @Autowired
    ISystemRuleAdviceService systemRuleAdviceService;
    @Autowired
    ICncProgramAdviceService cncProgramAdviceService;
    @Autowired
    ICncProgramService cncProgramService;
    @Autowired
    ToolBillAdviceMapper toolBillAdviceMapper;
    @Autowired
    ToolBillItemMapper toolBillItemMapper;

    /**
     * 查询机种、夹位当前版本刀具清单
     *
     * @param site
     * @param machineType
     * @param cncType
     * @return
     */
    public ToolBill selectToolBillByMachineTypeCncType( String site,  String machineType , String cncType ){
        /**检查站点*/
        siteAdviceService.existSite( site );
        /**检查机种*/
        itemGroupAdviceService.existItemGroup( site, machineType );
        /**检查夹位*/
        fieldGroupAdviceService.existFieldGroup( site , Constants.FIELD_GROUP_CncType , cncType );

        ToolBill toolBill = toolBillAdviceMapper.selectToolBillByMachineTypeCncType( site , machineType , cncType );
        return toolBill;
    }

    /**
     * 保存刀具清单
     *
     * @param toolBill
     * @param toolBillItems
     */
    @Transactional( propagation = Propagation.REQUIRED, rollbackFor = Exception.class )
    public void saveToolBill( ToolBill toolBill, ArrayList<ToolBillItem> toolBillItems ) {

        /**检查字段*/
        checkFieldsForToolBill( toolBill );

        /**刀具清单当前版本*/
        if( "true".equals( toolBill.getCurrentRevision() ) ){
            ToolBill currentRevToolBill = findCurrentRevToolBill( toolBill.getSite(), toolBill.getMachineType(), toolBill.getCncType() );
            if( currentRevToolBill != null ){
                ToolBill updateParam = new ToolBill();
                updateParam.setHandle( currentRevToolBill.getHandle() );
                updateParam.setCurrentRevision( "false" );
                toolBillService.updateToolBill( updateParam );
            }
        }

        /**保存刀具清单*/
        ToolBill _toolBill = null;
        _toolBill = findToolBill( toolBill.getSite(), toolBill.getMachineType(), toolBill.getCncType(), toolBill.getToolBillRevision() );
        if( _toolBill == null ){
            toolBill.setHandle( BOHandleUtil.builToolBillHandle( toolBill.getSite() , toolBill.getToolBillRevision(), toolBill.getCncType() ) );
            toolBill.setCreatedDateTime( new Date() );
            toolBill.setCreateUserBo( CommonMethods.getUserBo() );
            toolBillService.insertToolBill( toolBill );
        }else{
            toolBill.setHandle( _toolBill.getHandle() );
            toolBill.setCreatedDateTime( _toolBill.getCreatedDateTime() );
            toolBill.setUpdatedDateTime( new Date() );
            toolBill.setUpdateUserBo( CommonMethods.getUserBo() );
            toolBillService.updateToolBill( toolBill );
        }

        /**刀具清单当前版本变化，更新当前版本程式的刀具清单*/
        if( "true".equals( toolBill.getCurrentRevision() ) ){
            CncProgram currentRevCncProgram = cncProgramAdviceService.findCurrentRevCncProgram( toolBill.getSite(), toolBill.getMachineType(), toolBill.getCncType() );
            if( currentRevCncProgram != null ){
                CncProgram updateParam = new CncProgram();
                updateParam.setHandle( currentRevCncProgram.getHandle() );
                updateParam.setToolBillBo( toolBill.getHandle() );
                cncProgramService.updateCncProgram( updateParam );
            }
        }

        /**历史版本不允许更改明细*/
        if( isHistoryRevision( toolBill ) ){
            return;
        }

        /**删除旧刀具清单明细*/
        ToolBillItem queryParam = new ToolBillItem();
        queryParam.setToolBillBo( toolBill.getHandle() );
        List<ToolBillItem> toolBillItemList = toolBillItemService.selectToolBillItemList( queryParam );
        for( ToolBillItem toolBillItem : toolBillItemList ){
            toolBillItemMapper.deleteToolBillItemById( toolBillItem.getHandle() );
        }

        /**保存刀具清单明细*/
        for( ToolBillItem toolBillItem : toolBillItems ){
            /**检查字段*/
            checkFieldsForToolBillItem( toolBillItem );

            toolBillItem.setHandle( BOHandleUtil.builToolBillItemHandle( toolBill.getHandle(), toolBillItem.getToolLoc() ) );
            toolBillItem.setToolBillBo( toolBill.getHandle() );
            toolBillItem.setCreatedDateTime( toolBill.getCreatedDateTime() );
            toolBillItem.setCreateUserBo( toolBill.getCreateUserBo() );
            toolBillItem.setUpdatedDateTime( toolBill.getUpdatedDateTime() );
            toolBillItem.setUpdateUserBo( toolBillItem.getUpdateUserBo() );
            toolBillItemService.insertToolBillItem( toolBillItem );
        }
    }

    /**
     * 检查刀具清单字段
     *
     * @param toolBill
     */
    public void checkFieldsForToolBill( ToolBill toolBill ){
        /**检查站点*/
        siteAdviceService.existSite( toolBill.getSite() );
        /**检查机种*/
        itemGroupAdviceService.existItemGroup( toolBill.getSite(), toolBill.getMachineType() );
        /**检查夹位*/
        fieldGroupAdviceService.existFieldGroup( toolBill.getSite() , Constants.FIELD_GROUP_CncType , toolBill.getCncType() );
        /**检查刀具清单版本*/
        Assert.hasText( toolBill.getToolBillRevision() , I18nUtil.getI18nText( "production.cnctool.toolBillRevision" ) );
    }

    /**
     * 检查刀具清单明细项字段
     *
     * @param toolBillItem
     */
    public void checkFieldsForToolBillItem( ToolBillItem toolBillItem ){
        /**检查刀号*/
        Assert.hasText( toolBillItem.getToolLoc() ,I18nUtil.getI18nText("production.tool.toolLoc" ) );
        /**检查刀具名称*/
        Assert.hasText( toolBillItem.getToolDesc() ,I18nUtil.getI18nText("production.tool.toolDesc", new String[]{ toolBillItem.getToolLoc() } ) );
        /**检查刀具规格*/
        Assert.hasText( toolBillItem.getToolSpec() ,I18nUtil.getI18nText("production.tool.toolSpec", new String[]{ toolBillItem.getToolLoc() } ) );
        /**检查伸出长度*/
        Assert.isTrue( toolBillItem.getExtendLength() != null ,I18nUtil.getI18nText("production.tool.extendLength", new String[]{ toolBillItem.getToolLoc() } ) );
        /**检查有效刃长*/
        Assert.isTrue( toolBillItem.getBladeLength() != null ,I18nUtil.getI18nText("production.tool.bladeLength", new String[]{ toolBillItem.getToolLoc() } ) );
        /**检查筒夹*/
        Assert.hasText( toolBillItem.getCollet() ,I18nUtil.getI18nText("production.tool.collet", new String[]{ toolBillItem.getToolLoc() } ) );
        /**检查使用寿命*/
        Assert.isTrue( toolBillItem.getMaxUsage() != null ,I18nUtil.getI18nText("production.tool.maxUsageNotValid", new Object[]{ toolBillItem.getMaxUsage() } ) );
    }

    /**
     * 查询刀具清单
     *
     * @param machineType
     * @param cncType
     * @return
     */
    @Override
    public ToolBill findToolBill( String site, String machineType, String cncType, String toolBillRevision ) {

        /**检查站点*/
        Assert.hasText( site, I18nUtil.getI18nText( "common.siteNotBlank" ) );
        /**检查夹位*/
        Assert.hasText( cncType, I18nUtil.getI18nText( "production.cutter.cncType" ) );
        /**检查机种*/
        Assert.hasText( machineType, I18nUtil.getI18nText( "common.machineTypeNotBlank" ) );

        Map<String,Object> returnMap = new HashMap<>();

        ToolBill toolBill = null;
        if( StringUtils.isBlank( toolBillRevision ) ){
            toolBill = findCurrentRevToolBill( site, machineType, cncType );
            /*if( currentRevToolBill == null ){
                throw BusinessException.build("production.tool.ToolBillByMachineTypeCncType",new String[]{ machineType, cncType });
            }*/
        }else{
            ToolBill queryParam = new ToolBill();
            queryParam.setSite( site );
            queryParam.setMachineType( machineType );
            queryParam.setCncType( cncType );
            queryParam.setToolBillRevision( toolBillRevision );
            List<ToolBill> toolBills = toolBillService.selectToolBillList( queryParam );
            if( toolBills != null && toolBills.size() > 0 ){
                toolBill = toolBills.get( 0 );
                //throw BusinessException.build( "production.tool.toolBillRevisionNO",new String[]{ toolBillRevision } );
            }
        }

        return toolBill;
    }

    /**
     * 查询当前版本刀具清单
     *
     * @param site
     * @param machineType
     * @param cncType
     * @return
     */
    public ToolBill findCurrentRevToolBill( String site, String machineType, String cncType ){
        ToolBill queryParam = new ToolBill();
        queryParam.setSite( site );
        queryParam.setMachineType( machineType );
        queryParam.setCncType( cncType );
        queryParam.setCurrentRevision( "true" );
        List<ToolBill> toolBills = toolBillService.selectToolBillList( queryParam );
        if( toolBills != null && toolBills.size() > 0 ){
            return toolBills.get( 0 );
        }
        return null;
    }

    /**
     * 检查是否历史版本
     *
     * @param toolBill
     * @return
     */
    public boolean isHistoryRevision( ToolBill toolBill ){
        ToolBill queryParam = new ToolBill();
        queryParam.setSite( toolBill.getSite() );
        queryParam.setMachineType( toolBill.getMachineType() );
        queryParam.setCncType( toolBill.getCncType() );
        queryParam.setCreatedDateTime( toolBill.getCreatedDateTime() );
        List<ToolBill> toolBills = toolBillAdviceMapper.selectToolBillListByDate( queryParam );
        if( toolBills != null && toolBills.size() > 0 ){
            return true;
        }
        return false;
    }

}
